package com.moliku.insurance.process.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.moliku.insurance.common.constant.CompanyEnum;
import com.moliku.insurance.common.constant.InsureStatusEnum;
import com.moliku.insurance.common.constant.OrderEnum;
import com.moliku.insurance.common.constant.PolicyConfigKeyEnum;
import com.moliku.insurance.common.response.CommonInsureResult;
import com.moliku.insurance.common.util.ByteUtils;
import com.moliku.insurance.common.util.WebServiceUtil;
import com.moliku.insurance.common.util.XMLUtil;
import com.moliku.insurance.model.dto.eastSea.download.ESDownloadDTO;
import com.moliku.insurance.model.dto.eastSea.submit.ESInsuredInfoDTO;
import com.moliku.insurance.model.dto.eastSea.submit.EaseSeaInsertDTO;
import com.moliku.insurance.model.entity.Order;
import com.moliku.insurance.model.entity.OrderDetail;
import com.moliku.insurance.model.entity.eastSea.download.EastSeaDownload;
import com.moliku.insurance.model.entity.eastSea.submit.*;
import com.moliku.insurance.process.mapper.BaseOrderMapper;
import com.moliku.insurance.process.service.ConfigService;
import com.moliku.insurance.process.service.EastSeaService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 七分
 * @version 1.0
 * @date 2021/3/15 16:36
 * @effect
 */
@Slf4j
@AllArgsConstructor
@Service("EastSeaServiceImpl")
public class EastSeaServiceImpl implements EastSeaService {
    /**
     * 东海返回相应结果
     */
    private static final String PROPOSALRESPONSE = "ProposalResponse";
    /**
     * 东海返回的响应状态
     */
    private static final String RESPONSE_STATUS = "status";
    /**
     * 东海双审核状态
     */
    private static final CharSequence REDO_SH = "双审核";
    /**
     * 保单号
     */
    private static final String POLICY_NO = "policyNo";
    private final BaseOrderMapper baseOrderMapper;
    private final ConfigService configService;

    /**
     * 投保方法名
     */
    private final String SUBMIT_METHOD_NAME = "proposalService";
    /**
     * 下载方法名
     */
    private final String DOWNLOAD_METHOD_NAME = "downloadPdfService";
    /**
     * 投保参数名
     */
    private final String SUBMIT_PARAMTER_NAME = "requestXML";
    /**
     * 下载参数名
     */
    private final String DOWNLOAD_PARAMTER_NAME = "arg0";


    @Override
    public CommonInsureResult submitPolicy(EaseSeaInsertDTO dto) {
        //查询投保请求地址 以及命名空间
        String submitUrl = configService.getConfigValue(CompanyEnum.EAST_CHINA_SEA_SHIPPING, PolicyConfigKeyEnum.SUBMIT_POLICY_URL);
        String nameSpace = configService.getConfigValue(CompanyEnum.EAST_CHINA_SEA_SHIPPING, "nameSpace");

        Order order = baseOrderMapper.selectById(dto.getLocalOrderId());
        if (null == order) {
            log.info("东海投保失败,未查询到该订单:{}", dto.getLocalOrderId());
            return CommonInsureResult.submitPolicyFail(InsureStatusEnum.INSURE_FAIL_5102);
        }
        String xmlStr = getXmlStr(dto);
        log.info("参数:{}", xmlStr);
//        byte[] bytes = xmlStr.getBytes(StandardCharsets.UTF_8);
//        byte[] bytes1;
//        try {
//            bytes1 = ByteUtils.encryptByPublicKey(bytes, "D:\\soft\\certificate.cer");
//        } catch (Exception e) {
//            log.info("投保失败,错误信息为:{}", e.getMessage());
//            return CommonInsureResult.submitPolicyFail();
//        }
        //参数
        String response = WebServiceUtil.sendData(submitUrl, nameSpace, SUBMIT_METHOD_NAME, SUBMIT_PARAMTER_NAME, xmlStr);
//        String response = WebServiceUtil.sendData(URL, NAME_SPACE, SUBMIT_METHOD_NAME, SUBMIT_PARAMTER_NAME, bytes1);
        JSONObject object = JSONUtil.xmlToJson(response);
        log.info("东海投保返回:{}", object);
        //保存返回结果
        OrderDetail orderDetail = baseOrderMapper.selectDeatailByOrderId(order.getId());
        orderDetail.setInsureRsp(JSONUtil.toJsonStr(object));
        baseOrderMapper.updateOrderDeatailByOrderId(orderDetail);

        if (object.getJSONObject(PROPOSALRESPONSE).getStr(RESPONSE_STATUS).contains(REDO_SH)) {
            return CommonInsureResult.submitPolicySuccess(InsureStatusEnum.OPERATION_SUCCESS.getMessage());
        }

        if (ObjectUtil.isNotEmpty(object.getStr(POLICY_NO))) {
            order.setStatus(OrderEnum.CLOSED_NO_REFUND.getValue());
            order.setPolicyNo(object.getStr("policyNo"));
            baseOrderMapper.updateById(order);
            log.info("投保成功!");
            return CommonInsureResult.submitPolicySuccess(object.getStr("policyNo"));
        }
        log.info("投保失败,当前订单状态为:{}", object.getJSONObject("ProposalResponse").getStr("status"));
        log.info("投保失败,东海返回错误信息为:{}", object.getJSONObject("ProposalResponse").getStr("responseMessage"));
        return CommonInsureResult.submitPolicyFail(object.getJSONObject("ProposalResponse").getStr("status"));
    }

    /**
     * 拼接参数
     *
     * @param dto
     * @return
     */
    private String getXmlStr(EaseSeaInsertDTO dto) {
        //请求头
        ProposalEargoMain proposalEargoMain = new ProposalEargoMain();
        //流水号
        proposalEargoMain.setApplyNo(dto.getOrderDTO().getSerialNumber());
        //投保人被保人
        RelationList relationList = new RelationList();
        //投保人被保人集合
        List<ProposalEargoRelation> proposalEargoRelations = new ArrayList<>();
        //投保人
        ProposalEargoRelation proposalEargoRelation = new ProposalEargoRelation();
        proposalEargoRelation.setInsuredName(dto.getHolderDTO().getInsuredName());
        proposalEargoRelation.setIdentifyType(dto.getHolderDTO().getIdentifyType());
        proposalEargoRelation.setIdentifyNumber(dto.getHolderDTO().getIdentifyNumber());
        proposalEargoRelation.setBirthDate(DateUtil.format(DateUtil.parse(dto.getHolderDTO().getBirthDate()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoRelation.setMobile(dto.getHolderDTO().getMobile());
        proposalEargoRelation.setTaxPayerInd(dto.getHolderDTO().getTaxPayerInd());
        proposalEargoRelation.setContactName(dto.getHolderDTO().getContactName());
        proposalEargoRelation.setTaxNum(dto.getHolderDTO().getTaxNum());
        proposalEargoRelation.setTaxBankAccount(dto.getHolderDTO().getTaxBankAccount());
        proposalEargoRelation.setTaxAddress(dto.getHolderDTO().getTaxAddress());
        proposalEargoRelation.setTaxPhone(dto.getHolderDTO().getTaxPhone());
        proposalEargoRelation.setTaxPayBig(dto.getHolderDTO().getTaxPayBig());
        proposalEargoRelation.setPayPaySmall(dto.getHolderDTO().getPayPaySmall());
        proposalEargoRelation.setTaxPayBigName(dto.getHolderDTO().getTaxPayBigName());
        proposalEargoRelation.setPayPaySmallName(dto.getHolderDTO().getPayPaySmallName());
        proposalEargoRelation.setAddress(dto.getHolderDTO().getAddress());
        //投保人标识
        proposalEargoRelation.setFlag("1");
        proposalEargoRelation.setEmail(dto.getHolderDTO().getEmail());
        //投保人类型
        proposalEargoRelation.setType(dto.getHolderDTO().getType());
        //加入集合
        proposalEargoRelations.add(proposalEargoRelation);
        //被保人
        List<ESInsuredInfoDTO> insuredInfoDTOS = dto.getInsuredInfoDTOS();
        for (ESInsuredInfoDTO insuredInfoDTO : insuredInfoDTOS) {
            ProposalEargoRelation data = new ProposalEargoRelation();
            data.setInsuredName(insuredInfoDTO.getInsuredName());
            data.setIdentifyType(insuredInfoDTO.getIdentifyType());
            data.setIdentifyNumber(insuredInfoDTO.getIdentifyNumber());
            data.setMobile(insuredInfoDTO.getMobile());
            data.setType(dto.getHolderDTO().getType());
            data.setAddress(insuredInfoDTO.getAddress());
            //被保人标识
            data.setFlag("2");
            proposalEargoRelations.add(data);
        }
        //被保人投保人集合设定值
        relationList.setProposalEargoRelations(proposalEargoRelations);
        proposalEargoMain.setRelationList(relationList);

        //货物信息
        CargoList cargoList = new CargoList();
        //货物集合
        List<ProposalEargoCargo> proposalEargoCargos = new ArrayList<>();
        ProposalEargoCargo proposalEargoCargo = new ProposalEargoCargo();
        proposalEargoCargo.setCargoCode(dto.getOrderDTO().getCargoCode());
        proposalEargoCargo.setCargoName(dto.getOrderDTO().getCargoName());
        proposalEargoCargo.setDescription(dto.getOrderDTO().getDescription());
        proposalEargoCargo.setItemDetailName(dto.getOrderDTO().getItemDetailName());
        proposalEargoCargo.setPacking(dto.getOrderDTO().getPacking());

        proposalEargoCargos.add(proposalEargoCargo);
        cargoList.setProposalEargoCargos(proposalEargoCargos);
        proposalEargoMain.setCargoList(cargoList);

        //东海保险责任
        ItemKindList itemKindList = new ItemKindList();
        //保险责任集合s
        List<ProposalEargoItemKind> proposalEargoItemKinds = new ArrayList<>();

        ProposalEargoItemKind proposalEargoItemKind = new ProposalEargoItemKind();
        proposalEargoItemKind.setKindCode(dto.getOrderDTO().getKindCode());
        proposalEargoItemKind.setKindName(dto.getOrderDTO().getKindName());
        proposalEargoItemKind.setSumInsured(dto.getOrderDTO().getSumInsured());
        proposalEargoItemKind.setFlag(dto.getOrderDTO().getFlag());
        proposalEargoItemKind.setRate(dto.getOrderDTO().getRate());
        proposalEargoItemKind.setLiabCode(dto.getOrderDTO().getLiabCode());
        proposalEargoItemKind.setLiabName(dto.getOrderDTO().getLiabName());
        proposalEargoItemKinds.add(proposalEargoItemKind);
        itemKindList.setProposalEargoItemKinds(proposalEargoItemKinds);
        proposalEargoMain.setItemKindList(itemKindList);
        //标
        ProposalEargoItem proposalEargoItem = new ProposalEargoItem();
        proposalEargoItem.setStartDate(DateUtil.format(DateUtil.parse(dto.getOrderDTO().getStartDate()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoItem.setConveyanceType(dto.getOrderDTO().getConveyanceType());
        proposalEargoItem.setVesselCName(dto.getOrderDTO().getVesselCName());
        proposalEargoItem.setStartSiteCode(dto.getOrderDTO().getStartSiteCode());
        proposalEargoItem.setStartSiteName(dto.getOrderDTO().getStartSiteName());
        proposalEargoItem.setTargetSiteCode(dto.getOrderDTO().getTargetSiteCode());
        proposalEargoItem.setTargetSiteName(dto.getOrderDTO().getTargetSiteName());
        proposalEargoItem.setOriginalQuantity(dto.getOrderDTO().getOriginalQuantity());
        proposalEargoItem.setClaimAt(dto.getOrderDTO().getClaimAt());
        proposalEargoItem.setClaimAgentCode(dto.getOrderDTO().getClaimAgentCode());
        proposalEargoItem.setClaimAgentDesc(dto.getOrderDTO().getClaimAgentDesc());
        proposalEargoItem.setCurrency(dto.getOrderDTO().getCurrency());
        proposalEargoMain.setProposalEargoItem(proposalEargoItem);

        //日期
        ProposalEargoBase proposalEargoBase = new ProposalEargoBase();
        proposalEargoBase.setIssueDate(DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoBase.setInputDate(DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoBase.setStartDate(DateUtil.format(DateUtil.parse(dto.getOrderDTO().getStartDate()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoBase.setEndDate(DateUtil.format(DateUtil.parse(dto.getOrderDTO().getEndDate()), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'"));
        proposalEargoMain.setProposalEargoBase(proposalEargoBase);
        //用户
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName(dto.getOrderDTO().getUserName());
        userInfo.setPassword(dto.getOrderDTO().getPassword());
        proposalEargoMain.setUserInfo(userInfo);
        return XMLUtil.convertToXmlNoHead(proposalEargoMain);
    }

    @Override
    public CommonInsureResult downloadPolicy(ESDownloadDTO dto) {
        //查询投保请求地址 以及命名空间
        String submitUrl = configService.getConfigValue(CompanyEnum.EAST_CHINA_SEA_SHIPPING, PolicyConfigKeyEnum.SUBMIT_POLICY_URL);
        String nameSpace = configService.getConfigValue(CompanyEnum.EAST_CHINA_SEA_SHIPPING, "nameSpace");


        EastSeaDownload eastSeaDownload = new EastSeaDownload();
        eastSeaDownload.setUserName(dto.getUserName());
        eastSeaDownload.setPassword(dto.getPassword());
        eastSeaDownload.setIsPrint(dto.getIsPrint());
        eastSeaDownload.setPolicyNo(dto.getPolicyNo());
        //参数 xml
        String xmlStr = XMLUtil.convertToXmlNoHead(eastSeaDownload);
        byte[] bytes = xmlStr.getBytes(StandardCharsets.UTF_8);
        byte[] bytes1;
        try {
            bytes1 = ByteUtils.encryptByPublicKey(bytes, "D:\\soft\\certificate.cer");
        } catch (Exception e) {
            bytes1 = null;
            e.printStackTrace();
        }
//        String response = WebServiceUtil.sendData(URL, NAME_SPACE, DOWNLOAD_METHOD_NAME, DOWNLOAD_PARAMTER_NAME, bytes1);
        String response = WebServiceUtil.sendData(submitUrl, nameSpace, DOWNLOAD_METHOD_NAME, DOWNLOAD_PARAMTER_NAME, xmlStr);
        JSONObject object = JSONUtil.xmlToJson(response);
        log.info("东海下载返回:{}", object);
        if (ObjectUtil.isNotEmpty(object.getStr(POLICY_NO))) {
            //TODO
            return CommonInsureResult.downloadPolicySuccess(new byte[]{1, 2, 3});
        }
        return CommonInsureResult.downloadPolicyFail();
    }
}
